package main

import (
	"fmt"
	"runtime"
	"sync"
)

type student struct {
	Name string
	Age  int
}

//在range循环中，变量是不会随着遍历过程发生变化的。
//因此在代码中stu是不会变化的，变化的是放在&stu地址上的数据，
//因此最后m中value都将是最后一个放在&stu中的值
func pase_student() {
	m := make(map[string]*student)
	stus := []student{
		{Name: "zhou", Age: 24},
		{Name: "li", Age: 23},
		{Name: "wang", Age: 22},
	}
	for _, stu := range stus {
		m[stu.Name] = &stu
	}
	fmt.Printf("%+v", m)
	fmt.Println()
}

//先说说WaitGroup的用途：它能够一直等到所有的goroutine执行完成，并且阻塞主线程的执行，直到所有的goroutine执行完成。
//这里要注意一下，他们的执行结果是没有顺序的，调度器不能保证多个 goroutine 执行次序，且进程退出时不会等待它们结束。
//WaitGroup总共有三个方法：Add(delta int),Done(),Wait()。简单的说一下这三个方法的作用。
//Add:添加或者减少等待goroutine的数量
//Done:相当于Add(-1)
//Wait:执行阻塞，直到所有的WaitGroup数量变成0
func test3() {
	runtime.GOMAXPROCS(1) //设置只用一个协程
	wg := sync.WaitGroup{}
	wg.Add(20)
	for i := 0; i < 10; i++ {
		go func() {
			fmt.Println("i: ", i)
			wg.Done()
		}()
	}
	for i := 0; i < 10; i++ {
		go func(i int) {
			fmt.Println("--i: ", i)
			wg.Done()
		}(i)
	}
	wg.Wait()
}

type People struct{}

func (p *People) ShowA() {
	fmt.Println("showA")
	p.ShowB()
}
func (p *People) ShowB() {
	fmt.Println("showB")
}

type Human struct{}

func (h *Human) ShowA() {
	fmt.Println("Human showA")
}

type Teacher struct {
	Human
	People
}

func (t *Teacher) ShowB() {
	fmt.Println("teacher showB")
}

func calc(index string, a, b int) int {
	ret := a + b
	fmt.Println(index, a, b, ret)
	return ret
}

//这段代码有什么问题
type UserAges struct {
	ages map[string]int
	sync.Mutex
}

func (ua *UserAges) Add(name string, age int) {
	ua.Lock()
	defer ua.Unlock()
	ua.ages[name] = age
}

func (ua *UserAges) Get(name string) int {
	if age, ok := ua.ages[name]; ok {
		return age
	}
	return -1
}

//这个迭代有什么问题
//func (set *threadSafeSet) Iter() <-chan interface{} {
//	ch := make(chan interface{})
//	go func() {
//		set.RLock()
//
//		for elem := range set.s {
//			ch <- elem
//		}
//
//		close(ch)
//		set.RUnlock()
//
//	}()
//	return ch
//}

type People2 interface {
	Speak(string) string
}
type Student2 struct{

}
func (stu *Student2) Speak(think string) (talk string) {
	if think == "bitch" {
		talk = "You are a good boy"
	} else {
		talk = "hi"
	}
	return
}

func main(){
	pase_student()
	fmt.Println()
	test3()

	teacher := &Teacher{}
	teacher.Human.ShowA()


	//1、当程序运行到defer函数时，不会执行函数实现，但会将defer函数中的参数代码进行执行。
	//因此首先执行的是calc("10", a, b))，随后执行的是calc("2", a, calc("20", a, b))
	//得到第一行和第二行结果。
	//2、defer的执行结果是先进后出，从函数尾部向函数头部以此执行。因此会首先执行calc("2", a, calc("20", a, b))，
	//然后执行defer calc("1", a, calc("10", a, b))，相应打印第三行和第四行
	a := 1
	b := 2
	defer calc("1", a, calc("10", a, b)) // 10, 1, 2, 3
	a = 0
	defer calc("2", a, calc("20", a, b))
	b = 1

	//10, 1, 2, 3
	//20, 0, 2, 2

	//2, 0, 2, 2
	//1, 1, 3, 3




	var peo People2
	peo = &Student2{}
	think := "bitch"
	fmt.Println(peo.Speak(think))
}

